<?php
namespace App\Http\Controllers\Admin;

use App\Service\Admin\ItemService;
use App\Utilitys\Upload;
use Illuminate\Http\Request;
use ZipArchive as Zip;

class ItemController extends BaseController
{
    //项目库

    public function __construct(ItemService $service)
    {
        $this->db = $service;
    }

    //列表
    public function getIndex(Request $request)
    {
        $token = $request->post('token', '');
        $uid = $this->db->getUidByToken($token);
        if (!$uid) {
            return $this->toJson(-2, '没有登录');
        }
        $res = $this->db->getIndex();
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        return $this->toJson(0, '', $res['data']);
    }

    //详情
    public function getOne(Request $request)
    {
        $item_id = $request->post('item_id', 0);
        $res = $this->db->getOne($item_id);
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        return $this->toJson(0, '', $res['data']);
    }

    //上传压缩包
    public function upload(Request $request)
    {
        //exec('move '.env('ITEM_PATH').'public/upload/20240910 '.env('ITEM_PATH').'public/upload/20240910_1');
        //$res = $this->db->addPath('ai_items/172594944866dfe608537d9', 1, 2);
        //return $this->toJson(0, '', $res);
        $token = $request->post('token', '');
        $uid = $this->db->getUidByToken($token);
        if (!$uid) {
            return $this->toJson(-2, '没有登录');
        }
        $pas['type'] = $request->post('type', 1); //项目类型
        $pas['front'] = $request->post('front', 4); //前端技术栈
        $pas['back'] = $request->post('back', 10); //后端技术栈
        if ($pas['type'] != 1) {
            return $this->toJson(-2, '目前只有能网站');
        }
        if ($pas['front'] != 4) {
            return $this->toJson(-2, '目前只能原生');
        }
        $resUpload = Upload::uploadItem($request);
        if ($resUpload['code'] < 0) {
            return $this->toJson(-2, $resUpload['msg']);
        }
        $fs['fname'] = $resUpload['data']['origin'];
        $fs['forigin'] = $resUpload['data']['forigin'];
        $fs['folder'] = $resUpload['data']['folder'];
        $fs['fpath'] = $resUpload['data']['fpath'];
        $origins = explode('.', $fs['fname']);
        $resFile = $this->db->addFile($uid, $fs, $pas); //保存文件
        if ($resFile['code'] < 0) {
            return $this->toJson(-1, '文件保存失败');
        }
        $itemId = $resFile['data'];
        //解压缩
        $zip = new Zip();
        $resZip = $zip->open($fs['fpath']);
        if (!is_bool($resZip) || $resZip != true) {
            return $this->toJson(-2, '解压缩失败，错误代码：'.$resZip);
        }
        $zip->extractTo($fs['folder'].$fs['forigin']);
        $zip->close();
        //exec("tar -xf ".env('ITEM_PATH').$fpath." -C ".env('ITEM_PATH').$folder.$forigin);
        $dirs = scandir($fs['folder'].$fs['forigin']);
        //ddd(function_exists('exec'));
        //处理二级目录
        if (count($dirs)<=3 && $dirs[2] == $origins[0]) {
            $sourceDir = env('ITEM_PATH').'public/'.$fs['folder'].$fs['forigin'].'/'.$dirs[2];
            $midDir = env('ITEM_PATH').'public/'.$fs['folder'].time();
            $targetDir = env('ITEM_PATH').'public/'.$fs['folder'].$fs['forigin'];
            if (env('OS') == 'linux') {
                exec("mv $sourceDir $targetDir");
            } else {
                //exec("move $sourceDir $targetDir");
                exec("move $sourceDir $midDir"); //重命名
                rmdir($fs['folder'].$fs['forigin']); //删除
                exec("move $midDir $targetDir"); //重命名
            }
        }
        //复制到项目目录
        $targetDir = $fs['folder'].$fs['forigin'];
        $itemDir = 'ai_items/'.$fs['forigin'];
        $this->copydir($targetDir, $itemDir);
        if (!file_exists($itemDir)) {
            return $this->toJson(-2, '项目目录失败');
        }
        //保存文件树地址
        $treeArys = [
            'front_view' => [],
            'front_api' => [],
            'admin_view' => [],
            'admin_api' => [],
        ];
        $treeArys['front_view'] = $this->db->addPath($itemDir, $itemId, $uid);
        $itemArys = [
            'itemId' => $itemId,
            'itemName' => $origins[0],
            'treeList' => $treeArys,
        ];
        return $this->toJson(0, '', $itemArys);
    }

    //复制目录
    public function copydir($src, $dst)
    {
        if (!file_exists($dst)) mkdir($dst);
        $handle = opendir($src);
        while (($item=readdir($handle)) !== false) {
            if ($item == '.' || $item == '..') continue;
            $_src = $src.'/'.$item;
            $_dst = $dst.'/'.$item;
            if (is_file($_src)) copy($_src, $_dst);
            if (is_dir($_src)) $this->copydir($_src, $_dst);
        }
        closedir($handle);
    }

    //获取项目树
    public function itemOne(Request $request)
    {
        $fid = $request->post('fid', 0);
    }

    //读取文件内容
    public function read(Request $request)
    {
        $fid = $request->post('fid', 0);
        $res = $this->db->getFileOne($fid);
        if (empty($res)) {
            return $this->toJson(-2, '没有文件地址');
        }
        if (!file_exists($res['url'])) {
            return $this->toJson(-2, '没有文件');
        }
        $fdetail = file_get_contents($res['url']);
        return $this->toJson(0, '', $fdetail);
    }

    //保存文件
    public function save(Request $request)
    {
        $fid = $request->post('fid', 0);
        $fdetail = $request->post('fdetail', '');
        $res = $this->db->getFileOne($fid);
        if (empty($res)) {
            return $this->toJson(-2, '没有文件地址');
        }
        if (!$fdetail) {
            return $this->toJson(-2, '没有文件内容');
        }
        if (!file_exists($res['url'])) {
            return $this->toJson(-2, '没有文件');
        }
        file_put_contents($res['url'], $fdetail);
        return $this->toJson();
    }

    //导出
    public function export(Request $request)
    {
        $item_id = $request->post('item_id', 0);
        $res = $this->db->getOne($item_id);
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        $fname = $res['data']['en'];
        $sourceDir = 'ai_items/'.$res['data']['en'];
        if (!file_exists($sourceDir)) {
            return $this->toJson(-2, '文件不存在');
        }
        //压缩
        $randTime = time();
        if (!class_exists('ZipArchive')) {
            //echo "ZipArchive extension is installed.";
            return $this->toJson(-2, '压缩程序没有安装');
        }
        $targetDir = env('ITEM_PATH').'public/'.$sourceDir.'_'.$randTime.'.zip';
        $zip = new Zip();
        if (!$zip->open($targetDir, Zip::CREATE | Zip::OVERWRITE)) {
            return $this->toJson(-2, "无法打开压缩包 $targetDir");
        }
        $this->addFileToZip($sourceDir, $sourceDir, $zip);
        $zip->close();
        $fpath = env('DOMAIN').'/api/admin/item/down?zipName='.$fname.'_'.$randTime.'.zip';
        return $this->toJson(0, '', $fpath);
        //$fpath = $fname.'_'.$randTime.'.zip';
        //return redirect('/api/admin/item/down?zipName='.$fpath);
    }

    /**
     * 压缩目录
     * @param string $path 电脑绝对地址
     * @param string $fpath 项目相对地址
     * @param object $zip 压缩对象
     */
    public function addFileToZip($path, $fpath, $zip)
    {
        $handle = opendir($path);
        while (($fname=readdir($handle)) !== false) {
            if (!in_array($fname, ['.', '..'])) {
                if (is_dir($path.'/'.$fname)) {
                    $this->addFileToZip($path.'/'.$fname, $fpath, $zip);
                } else {
                    $zip->addFile($path.'/'.$fname, $fpath.'/'.$fname);
                }
            }
        }
        @closedir();
    }

    //下载zip
    public function down(Request $request)
    {
        $zipName = $request->get('zipName', '');
        header('Content-Type: application/zip');
        header('Content-disposition: attachment; filename=' . basename($zipName));
        header('Content-Length: '. filesize($zipName));
        readfile($zipName);
    }

    //设置管理后台页面
    public function setAdmin(Request $request)
    {
        $token = $request->post('token', '');
        $uid = $this->db->getUidByToken($token);
        if (!$uid) {
            return $this->toJson(-2, '没有登录');
        }
        $item_id = $request->post('item_id', 0);
        $path = 'ai_items/admin/fxotary';
        $res = $this->readAdmin($path, $uid, $item_id);
        return $this->toJson(0, '', $res);
    }

    /**
     * 读取后台模板
     */
    public function readAdmin($dirpath = '', $uid, $item_id, $pid = 0)
    {
        $dirpath = $dirpath ? $dirpath : 'ai_items/admin/fxotary';
        $dirs = scandir($dirpath);
        $treeArys = [];
        foreach ($dirs as $v) {
            if (!in_array($v, ['.', '..', 'lib', 'static', 'temp'])) {
                $childList = [];
                $addArys = [
                    'uid' => $uid, 'item_id' => $item_id,
                    'title' => $v, 'url' => $dirpath,
                    'pid' => $pid, 'client_type' => 1,
                ];
                $lastid = $this->db->addNewPath($addArys);
                if (is_dir($dirpath.'/'.$v)) {
                    $childList = $this->readAdmin($dirpath.'/'.$v, $uid, $item_id, $lastid);
                }
                $treeArys[] = [
                    'fname' => $v,
                    'childList' => $childList,
                ];
            }
        }
        return $treeArys;
    }
}